0398. 随机数索引【中等】
1. 📝 题目描述
给你一个可能含有 重复元素 的整数数组 nums,请你随机输出给定的目标数字 target 的索引。你可以假设给定的数字一定存在于数组中。
实现 Solution 类:
Solution(int[] nums)用数组nums初始化对象。int pick(int target)从nums中选出一个满足nums[i] == target的随机索引i。如果存在多个有效的索引,则每个索引的返回概率应当相等。
示例:
txt
输入
["Solution", "pick", "pick", "pick"]
[[[1, 2, 3, 3, 3]], [3], [1], [3]]
输出
[null, 4, 0, 2]
解释
Solution solution = new Solution([1, 2, 3, 3, 3]);
solution.pick(3); // 随机返回索引 2, 3 或者 4 之一。每个索引的返回概率应该相等。
solution.pick(1); // 返回 0。因为只有 nums[0] 等于 1。
solution.pick(3); // 随机返回索引 2, 3 或者 4 之一。每个索引的返回概率应该相等。1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
提示:
1 <= nums.length <= 2 * 10^4-2^31 <= nums[i] <= 2^31 - 1target是nums中的一个整数- 最多调用
pick函数10^4次
2. 🎯 s.1 - 蓄水池抽样
c
typedef struct {
int* nums;
int size;
} Solution;
Solution* solutionCreate(int* nums, int numsSize) {
Solution* obj = (Solution*)malloc(sizeof(Solution));
obj->nums = nums;
obj->size = numsSize;
return obj;
}
int solutionPick(Solution* obj, int target) {
int res = 0, count = 0;
for (int i = 0; i < obj->size; i++) {
if (obj->nums[i] == target) {
count++;
if (rand() % count == 0) res = i;
}
}
return res;
}
void solutionFree(Solution* obj) { free(obj); }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
js
/**
* @param {number[]} nums
*/
var Solution = function (nums) {
this.nums = nums
}
/**
* @param {number} target
* @return {number}
*/
Solution.prototype.pick = function (target) {
let res = 0,
count = 0
for (let i = 0; i < this.nums.length; i++) {
if (this.nums[i] === target) {
count++
if (Math.random() < 1 / count) res = i
}
}
return res
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
py
class Solution:
def __init__(self, nums: List[int]):
self.nums = nums
def pick(self, target: int) -> int:
res, count = 0, 0
for i, num in enumerate(self.nums):
if num == target:
count += 1
if random.randint(1, count) == 1:
res = i
return res1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
- 时间复杂度:初始化
,pick - 空间复杂度:
(不计输入数组)
算法思路:
- 蓄水池抽样:遍历时,第
个等于target的元素以 的概率被选中 - 保证每个符合条件的索引被等概率返回